home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / svgakt50.zip / INCLUDE / MODEL.MAC < prev    next >
Text File  |  1994-08-22  |  14KB  |  483 lines

  1. ;****************************************************************************
  2. ;*
  3. ;*                  Copyright (C) 1994 SciTech Software.
  4. ;*                          All rights reserved.
  5. ;*
  6. ;* Filename:    $RCSfile: model.mac $
  7. ;* Version:     $Revision: 1.5 $
  8. ;*
  9. ;* Language:    Turbo Assembler 3.0
  10. ;* Environment: IBM PC (MS DOS)
  11. ;*
  12. ;* Description: Macros to provide memory model independant assembly language
  13. ;*              module for C programming. Supports the large memory model
  14. ;*              and 386 extended DOS memory models.
  15. ;*
  16. ;*              The defines that you should use when assembling modules that
  17. ;*                use this macro package are:
  18. ;*
  19. ;*                  __LARGE__    Assemble for real mode large memory model
  20. ;*                  __X386__    Assemble for 386 extended memory model
  21. ;*                  __FLAT__    Assemble for 386 FLAT memory model
  22. ;*                  __8086__    Assemble for 8086 real mode code
  23. ;*                    __80286__    Assemble for 80286 real mode code
  24. ;*                    __COMM__    Declare global variables as COMMunal
  25. ;*
  26. ;*                By default the real mode large memory model targeted for the
  27. ;*                80386 processor is selected.
  28. ;*
  29. ;*              Note that we use the TASM simplified segment directives so
  30. ;*              that 32 bit code will assemble correctly, and we also use
  31. ;*              TASM's IDEAL mode syntax, so this is not compatible with
  32. ;*              MASM. The __FLAT__ mode should be used whenever possible to
  33. ;*              assemble code that needs to be converted to Unix style .o
  34. ;*              files for DJGPP and EMX, and for most new compilers. Symantec
  35. ;*              C++ however requires the __X386__ memory model, or it will not
  36. ;*              link correctly). You should specify either of __X386__ or
  37. ;*              __FLAT__ to assemble code correctly.
  38. ;*
  39. ;*                The main intent of the macro file is to enable programmers
  40. ;*                to write _one_ set of source that can be assembled to run
  41. ;*                in either 16 bit real and protected modes or 32 bit
  42. ;*                protected mode without the need to riddle the code with
  43. ;*                'if flatmodel' style conditional assembly (it is still there
  44. ;*                but nicely hidden by a macro layer that enhances the
  45. ;*                readability and understandability of the resulting code).
  46. ;*
  47. ;* NOTES:   When you declare the data and code segments, you should specify
  48. ;*          a name to be used. This name should be the name of the file
  49. ;*          being assembled, but you may use the same name for mutiple
  50. ;*          modules if you wish so that the data and code for these modules
  51. ;*          are all contained in the same segments. Of course the maximum
  52. ;*          size of data and code must be less than 64k respectively.
  53. ;*
  54. ;* $Id: model.mac 1.5 1994/08/22 07:58:32 kjb release $
  55. ;*
  56. ;****************************************************************************
  57.  
  58.         IDEAL
  59.  
  60. ; Define symbols codesize and datasize depending on the requested memory
  61. ; model. Note that because of the differences in addressing used in the
  62. ; 16 and 32 bit memory models, we need a couple of macros to define things
  63. ; such as what register is used for looping (CX or ECX) etc. Note that we
  64. ; can use simple 16 bit code in 32 bit mode and vice-versa, but unless this
  65. ; is absolutely necessary it poses the performance hit of requiring an
  66. ; operand size prefex for the instruction. Hence if we simply need to use
  67. ; a set of registers for an operation, use the macros to use the best
  68. ; register for the current mode of operation. Of course the real registers
  69. ; may be specified for operations that specifically require 16 or 32 bits.
  70. ;
  71. ; The following things are defined:
  72. ;
  73. ;    UCHAR    - Typedef for a character type
  74. ;   USHORT - Typedef for a short type
  75. ;    UINT    - Typedef for an integer type
  76. ;    BOOL    - Typedef for a boolean type
  77. ;   DPTR    - Operand size of data pointers
  78. ;   DDIST   - Distance to data variables (NEAR or FAR)
  79. ;   CPTR    - Operand size of code pointers
  80. ;    FCPTR    - Operand size of far code pointers
  81. ;    NCPTR    - Operand size of near code pointers
  82. ;   FPTR    - Function pointer modifier, either NEAR or FAR
  83. ;    _AX        - General accumulator register, either AX or EAX
  84. ;    _BX        - General base register, either BX or EBX
  85. ;   _CX        - Loop counter register, either CX or ECX
  86. ;   CXPTR   - Operand size of loop counter, either WORD or DWORD
  87. ;   _DX        - General data register, either DX or EDX
  88. ;    _SI        - Source index register, either SI or ESI
  89. ;    _DI        - Destination index register, either DI or EDI
  90. ;    _BP        - Base pointer register, either BP or EBP
  91. ;    _SP        - Stack pointer register, either SP or ESP
  92. ;    _ES        - ES segment override - evaluates to nothing in 32 bit PM
  93.  
  94. ifdef   __FLAT__
  95.         __X386__ = 1
  96. endif
  97.  
  98. ifdef   __X386__
  99.         flatmodel    EQU    1        ; This is a flat memory model
  100.         datasize    EQU 0       ; Near data memory model
  101.         dptrsize    EQU 4       ; Size of a data pointer (32 bit near)
  102.         stackalign  EQU 4       ; Align stack to 4 byte boundary
  103.         typedef UCHAR BYTE        ; Size of a character
  104.         typedef USHORT WORD        ; Size of a short
  105.         typedef UINT DWORD        ; Size of an integer
  106.         typedef ULONG DWORD        ; Size of a long
  107.         typedef BOOL WORD        ; Size of a boolean
  108.         typedef DPTR DWORD        ; Size of a data pointer
  109.         typedef FDPTR FWORD        ; Size of a far data pointer
  110.         typedef    NDPTR DWORD        ; Size of a near data pointer
  111.         DDIST       EQU NEAR
  112.         codesize    EQU 0       ; Near code memory model
  113.         cptrsize    EQU 4
  114.         typedef CPTR DWORD        ; Size of a code pointer
  115.         typedef FCPTR FWORD        ; Size of a far code pointer
  116.         typedef NCPTR DWORD        ; Size of a near code pointer
  117.         FPTR        EQU NEAR
  118.         _AX            EQU    EAX        ; EAX is used for accumulator
  119.         _BX            EQU    EBX        ; EBX is used for accumulator
  120.         _CX            EQU ECX     ; ECX is used for looping
  121.         CXPTR        EQU    DWORD    ; loop variables are 32 bits
  122.         _DX            EQU    EDX        ; EDX is used for data register
  123.         _SI            EQU    ESI        ; ESI is the source index register
  124.         _DI            EQU    EDI        ; EDI is the destination index register
  125.         _BP            EQU    EBP        ; EBP is used for base pointer register
  126.         _SP            EQU    ESP        ; ESP is used for stack pointer register
  127.         _ES            EQU            ; ES and DS are the same in 32 bit PM
  128.         P386                    ; Turn on 386 code generation
  129. ifdef   __FLAT__
  130.         MODEL       FLAT        ; Set up for 32 bit simplified FLAT model
  131. else
  132.         LARGESTACK              ; Set up for a 32 bit stack model
  133. endif
  134. else
  135.         flatmodel    EQU    0        ; This is a segmented memory model
  136.         datasize    EQU 1       ; Far data memory model
  137.         dptrsize    EQU 4       ; Size of a data pointer
  138.         stackalign  EQU 2       ; Align stack to 2 byte boundary
  139.         typedef UCHAR BYTE      ; Size of a character
  140.         typedef USHORT WORD        ; Size of a short
  141.         typedef UINT WORD        ; Size of an integer
  142.         typedef ULONG DWORD        ; Size of a long
  143.         typedef BOOL WORD        ; Size of a boolean
  144.         typedef DPTR DWORD        ; Size of a data pointer
  145.         typedef FDPTR DWORD        ; Size of a far data pointer
  146.         typedef    NDPTR WORD        ; Size of a near data pointer
  147.         DDIST       EQU FAR
  148.         codesize    EQU 1       ; Far code memory model
  149.         cptrsize    EQU 4       ; Size of a code pointer
  150.         typedef CPTR DWORD        ; Size of a code pointer
  151.         typedef FCPTR DWORD        ; Size of a far code pointer
  152.         typedef NCPTR WORD        ; Size of a near code pointer
  153.         FPTR        EQU FAR
  154.         _AX            EQU    AX        ; AX is used for accumulator
  155.         _BX            EQU    BX        ; BX is used for accumulator
  156.         _CX            EQU CX         ; CX is used for looping
  157.         CXPTR        EQU    WORD    ; loop variables are 16 bits
  158.         _DX            EQU    DX        ; DX is used for data register
  159.         _SI            EQU    SI        ; SI is the source index register
  160.         _DI            EQU    DI        ; DI is the destination index register
  161.         _BP            EQU    BP        ; BP is used for base pointer register
  162.         _SP            EQU    SP        ; SP is used for stack pointer register
  163.         _ES            EQU es:        ; ES is used for segment override
  164. ifndef    __8086__
  165. ifdef    __80286__
  166.         P286                    ; Turn on 286 code generation
  167. else
  168.         P386                    ; Turn on 386 code generation
  169. endif
  170. endif
  171. endif
  172.  
  173. ; Macros for declaring external global variables
  174.  
  175. ifdef   __COMM__
  176. MACRO   $EXTRN      name,type
  177.         COMM        DDIST name:type
  178. ENDM
  179. else
  180. MACRO   $EXTRN      name,type
  181.         EXTRN       name:type
  182. ENDM
  183. endif
  184.  
  185. ; Macros for entering and exiting C callable functions. Note that we must
  186. ; always save and restore the SI and DI registers for C functions, and for
  187. ; 32 bit C functions we also need to save and restore EBX and clear the
  188. ; direction flag.
  189.  
  190. MACRO    enter_c    LocalSize
  191. ifdef    __8086__
  192.         push    bp
  193.         mov        bp,sp
  194.         sub        sp,LocalSize
  195. else
  196.         enter    LocalSize,0
  197. ifdef    __X386__
  198.         push    ebx
  199. endif
  200. endif
  201.         push    _si
  202.         push    _di
  203. ENDM
  204.  
  205. MACRO    leave_c
  206.         pop        _di
  207.         pop        _si
  208. ifdef    __X386__
  209.         pop        ebx
  210. endif
  211.         cld
  212. ifdef    __8086__
  213.         mov        sp,bp
  214.         pop        bp
  215. else
  216.         leave
  217. endif
  218. ENDM
  219.  
  220. MACRO   use_ebx
  221. if flatmodel
  222.         push    ebx
  223. endif
  224. ENDM
  225.  
  226. MACRO   unuse_ebx
  227. if flatmodel
  228.         pop     ebx
  229. endif
  230. ENDM
  231.  
  232. ; Macros for saving and restoring the value of DS,ES,FS,GS when it is to
  233. ; be used in assembly routines. This evaluates to nothing in the flat memory
  234. ; model, but is saves and restores DS in the normal memory model.
  235.  
  236. MACRO    use_ds
  237. ife flatmodel
  238.         push    ds
  239. endif
  240. ENDM
  241.  
  242. MACRO    unuse_ds
  243. ife flatmodel
  244.         pop        ds
  245. endif
  246. ENDM
  247.  
  248. MACRO    use_es
  249. ife flatmodel
  250.         push    es
  251. endif
  252. ENDM
  253.  
  254. MACRO    unuse_es
  255. ife flatmodel
  256.         pop        es
  257. endif
  258. ENDM
  259.  
  260. ; Macros for loading the address of a data pointer into a segment and
  261. ; index register pair. The macro explicitly loads DS or ES in the 16 bit
  262. ; memory model, or it simply loads the offset into the register in the flat
  263. ; memory model since DS and ES always point to all addressable memory. You
  264. ; must use the correct _REG (ie: _BX) macros for documentation purposes.
  265.  
  266. MACRO    _lds    reg, addr
  267. if flatmodel
  268.         mov     reg,addr
  269. else
  270.         lds        reg,addr
  271. endif
  272. ENDM
  273.  
  274. MACRO   _les    reg, addr
  275. if flatmodel
  276.         mov     reg,addr
  277. else
  278.         les        reg,addr
  279. endif
  280. ENDM
  281.  
  282. ; Macros for setting the value of the DS,ES,FS,GS registers to the same
  283. ; value. This is does nothing in 32 bit protected mode.
  284.  
  285. MACRO    es_eq_ds
  286. ife flatmodel
  287.         push    ds
  288.         pop        es
  289. endif
  290. ENDM
  291.  
  292. MACRO    ds_eq_es
  293. ife flatmodel
  294.         push    es
  295.         pop        ds
  296. endif
  297. ENDM
  298.  
  299. MACRO    fs_eq_ds
  300. ife flatmodel
  301.         push    ds
  302.         pop        fs
  303. endif
  304. ENDM
  305.  
  306. ; Macro for loading a value into a register given a pointer and an
  307. ; offset from the pointer. Will work in either 16 and 32 bit mode.
  308. ;
  309. ; NOTE: The value of BX or EBX will be trashed over this macro!!
  310.  
  311. MACRO    get_val reg, pointer, offset
  312. if flatmodel
  313.         mov        ebx,[pointer]
  314.         mov        reg,[ebx + offset]
  315. else
  316.         les     bx,[pointer]
  317.         mov        reg,[es:bx + offset]
  318. endif
  319. ENDM
  320.  
  321. ; Macros for adding and subtracting a value from registers. Two value are
  322. ; provided, one for 16 bit modes and another for 32 bit modes (the extended
  323. ; register is used in 32 bit modes).
  324.  
  325. MACRO   _add    reg, val16, val32
  326. if flatmodel
  327.         add        e®&, val32
  328. else
  329.         add        reg, val16
  330. endif
  331. ENDM
  332.  
  333. MACRO    _sub    reg, val16, val32
  334. if flatmodel
  335.         sub        e®&, val32
  336. else
  337.         sub        reg, val16
  338. endif
  339. ENDM
  340.  
  341. ; Macro to clear the high order word for the 32 bit extended registers.
  342. ; This is used to convert an unsigned 16 bit value to an unsigned 32 bit
  343. ; value, and will evaluate to nothing in 16 bit modes.
  344.  
  345. MACRO    clrhi    reg
  346. if flatmodel
  347.         and        reg, 0FFFFh        ; Mask out top 16 bit
  348. endif
  349. ENDM
  350.  
  351. ; Macro to load an extended register with an integer value in either mode
  352.  
  353. MACRO    loadint    reg,val
  354. if flatmodel
  355.         mov        e®&,val
  356. else
  357.         xor        e®&,e®&
  358.         mov     reg,val
  359. endif
  360. ENDM
  361.  
  362. ; Macros for procedure definitions given a name. Note that they also export
  363. ; the symbol with the PUBLIC directive, so that it need not be explicitly
  364. ; exported.
  365.  
  366. MACRO   procstart name          ; Set up model independant proc
  367. if codesize                     ; and export name
  368. PROC    name FAR
  369. else
  370. PROC    name NEAR
  371. endif
  372.         PUBLIC name
  373. ENDM
  374.  
  375. MACRO   procstatic name         ; Set up model independant private proc
  376. if codesize
  377. PROC    name FAR
  378. else
  379. PROC    name NEAR
  380. endif
  381. ENDM
  382.  
  383. MACRO   procnear name           ; Set up near proc
  384. PROC    name NEAR               ; and export name
  385.         PUBLIC name
  386. ENDM
  387.  
  388. MACRO   procfar name            ; Set up far proc
  389. PROC    name FAR                ; and export name
  390.         PUBLIC name
  391. ENDM
  392.  
  393. MACRO   procend name            ; End procedure macro
  394. ENDP    name
  395. ENDM
  396.  
  397. ; Macros for the _DATA data segment. This segment contains initialised data.
  398.  
  399. MACRO   begdataseg name
  400. ifdef   __FLAT__
  401.         DATASEG
  402. else
  403. if flatmodel
  404. SEGMENT _DATA DWORD PUBLIC USE32 'DATA'
  405. else
  406. SEGMENT _DATA WORD PUBLIC 'DATA'
  407. endif
  408. endif
  409. ENDM
  410.  
  411. MACRO   enddataseg name
  412. ifndef  __FLAT__
  413. ENDS    _DATA
  414. endif
  415. ENDM
  416.  
  417. ; Macros for the _BSS data segment. This segment contains initialised data.
  418.  
  419. MACRO   begbssseg name
  420. ifdef   __FLAT__
  421.         DATASEG
  422. else
  423. if flatmodel
  424. SEGMENT _BSS DWORD PUBLIC USE32 'BSS'
  425. else
  426. SEGMENT _BSS WORD PUBLIC 'BSS'
  427. endif
  428. endif
  429. ENDM
  430.  
  431. MACRO   endbssseg name
  432. ifndef  __FLAT__
  433. ENDS    _BSS
  434. endif
  435. ENDM
  436.  
  437. ; Macro to be invoked at the start of all modules to set up segments for
  438. ; later use.
  439.  
  440. MACRO   header name
  441. begdataseg name
  442. enddataseg name
  443. begbssseg  name
  444. endbssseg  name
  445. ENDM
  446.  
  447. ; Macro for the main code segment.
  448.  
  449. MACRO   begcodeseg name
  450. ifdef   __FLAT__
  451.         CODESEG
  452.         ASSUME  CS:FLAT,DS:FLAT
  453. else
  454. if flatmodel
  455. SEGMENT _TEXT DWORD PUBLIC USE32 'CODE'
  456. GROUP   DGROUP _DATA,_BSS
  457.         ASSUME  CS:_TEXT,DS:DGROUP
  458. else
  459. SEGMENT &name&_TEXT BYTE PUBLIC 'CODE'
  460. GROUP   DGROUP _DATA,_BSS
  461.         ASSUME CS:&name&_TEXT,DS:DGROUP
  462. endif
  463. endif
  464. ENDM
  465.  
  466. MACRO   endcodeseg name
  467. ifndef  __FLAT__
  468. if flatmodel
  469. ENDS    _TEXT
  470. else
  471. ENDS    &name&_TEXT
  472. endif
  473. endif
  474. ENDM
  475.  
  476. ; Boolean truth values (same as those in debug.h)
  477.  
  478. False        =    0
  479. True        =    1
  480. No            =    0
  481. Yes            =    1
  482.  
  483.